<?php
/*
 * @Author: 李志刚
 * @CopyRight: 2022-2099 李志刚（854378082@qq.com）
 * @Date: 2020-02-29 22:47:24
 * @Description: 无限级别分类表更新、树形菜单生成
 * @LastEditors: 李志刚
 * @LastEditTime: 2023-01-19 10:34:40
 * @FilePath: \www.firefly.com\app\Customize\Tree.php
 */

declare(strict_types=1);

namespace App\Customize;

class Tree {
	// 权限菜单转成树形菜单数组
	public function menuToTree($data, $pid)
	{
		$tree = [];
		if ($data->count() > 0) {
			foreach ($data as $v) {
				if ($v->parentid == $pid) {
					$v = ['menu_id' => $v->id, 'title' => $v->name, 'expand' => true];
					$v['children'] = $this->menuToTree($data, $v['menu_id']);
					$tree[] = $v;
				}
			}
		}
		return $tree;
	}
	// 角色权限选择转成树形菜单数组
	public function rolePrivToTree($priv, $data, $pid)
	{
		$tree = [];
		if ($data->count() > 0) {
			foreach ($data as $v) {
				if ($v->parentid == $pid) {
					$v = ['menu_id' => $v->id, 'title' => $v->name, 'expand' => false];
					// 所有子菜单都选中的时候，此菜单选中checked，部分选中时selected
					$child_count = $data->where('parentid', $v['menu_id'])->count();
					// 没有子菜单的时候，判断他本身
					if ($child_count == 0) {
						$v['checked'] = $priv->where('menu_id', $v['menu_id'])->count() > 0 ? true : false;
					}
					$v['children'] = $this->rolePrivToTree($priv, $data, $v['menu_id']);
					$tree[] = $v;
				}
			}
		}
		return $tree;
	}
	// 转成树形数组
	public function typeToTree($data, $pid)
	{
		$tree = [];
		if ($data->count() > 0) {
			foreach ($data as $v) {
				if ($v->parentid == $pid) {
					$v = $v->toArray();
					$v['childs'] = $this->typeToTree($data, $v['id']);
					$tree[] = $v;
				}
			}
		}
		return $tree;
	}
	// 转成树形表格用的数据，这个有点坑，必须定义一个循环外的变量来返回，循环内变量会被覆盖导致数据出错
	private $res = [];
	public function toTableTree($data, $pid = 0)
	{
		if (is_null($data) || $data == '') {
			return $this->res;
		}
		foreach ($data as $v) {
			// 计算level
			$left = 0;
			$level = count(explode(',', $v['arrparentid']));
			$str = '';
			if ($level > 1) {
				$str .= '|—';
				$left = 10 * $level;
			}
			$res = $v;
			$res['name'] = $str . $v['name'];
			$res['left'] = $left;
			$this->res[] = $res;
			if ($v['childs'] != '') {
				$this->toTableTree($v['childs'], $pid);
			}
		}
		return $this->res;
	}
	// 通用转成树形菜单数组
	public function toTree($data, $pid) {
		$tree = [];
		if ($data->count() > 0) {
			foreach ($data as $v) {
				if ($v->parentid == $pid) {
					$v = $v->toArray();
					$v['parentid'] = $this->toTree($data, $v['id']);
					$tree[] = $v;
				}
			}
		}
		return $tree;
	}
	// 树形菜单 html
	public function toTreeSelect($tree, $pid = 0) {
		$html = '';
		if (is_null($tree) || $tree == '') {
			return $html;
		}
		foreach ($tree as $v) {
			// 计算level
			$level = count(explode(',', $v['arrparentid']));
			$str = '';
			if ($level > 1) {
				for ($i = 2; $i < $level; $i++) {
					$str .= '| ';
				}
				$str .= ' |—';
			}
			// level < 4 是为了不添加更多的层级关系，其它地方不用判断，只是后台菜单不用那么多级
			if ($pid == $v['id']) {
				if ($level == 1) {
					$html .= "<option value='" . $v['id'] . "' selected='selected' style='font-weight:bold;'>" . $str . $v['name'] . "</option>";
				} else {
					$html .= "<option value='" . $v['id'] . "' selected='selected'>" . $str . $v['name'] . "</option>";
				}
			} else {
				if ($level == 1) {
					$html .= "<option value='" . $v['id'] . "' style='font-weight:bold;'>" . $str . $v['name'] . "</option>";
				} else {
					$html .= "<option value='" . $v['id'] . "'>" . $str . $v['name'] . "</option>";
				}
			}
			if ($v['parentid'] != '') {
				$html .= $this->toTreeSelect($v['parentid'], $pid);
			}
		}
		return $html;
	}
}